#pragma once
#include "Util.hpp"
#include "config.hpp"
#include "data.hpp"
#include "hot.hpp"
#include "service.hpp"
#include <vector>
#include <thread>


void TestUtil(const std::string& filename)
{
  shy::FileUtil fu(filename);
  std::cout << fu.FileName() << std::endl;
  std::cout << fu.FileSize() << std::endl;
  std::cout << fu.LastAccessTime() << std::endl;
  std::cout << fu.LastModifyTime() << std::endl;


  std::string body;
  fu.GetContent(body);

  shy::FileUtil nfu("test.txt");
  nfu.SetContent(body);
  return;
}

void TestUtiltcompress(std::string& filename)
{
  // packed
  shy::FileUtil fu(filename);
  std::string packedname = filename + ".lz";

  fu.Compress(packedname);
  // unpacked 
  std::string unpackedname = "hello.txt";
  shy::FileUtil fup(packedname);
  fu.uncompress(unpackedname);
}

void TestUtilDirectory(std::string& filename)
{
  shy::FileUtil fu(filename);
  fu.CreateDirectory();
  if (fu.Exists())
  {
    std::vector<std::string> arry;
    fu.ScanDirectory(arry);

    for (auto& fn : arry)
    {
      std::cout << fn << std::endl;
    }
  }

}

void TestSerialize()
{
  const char* name = "xiaoming";
  int age = 18;
  float score[3] = {90 , 91 , 98};
  Json::Value root;
  root["name"] = name;
  root["age"] = age; 
  root["score"].append(score[0]);
  root["score"].append(score[1]);
  root["score"].append(score[2]);
  std::string json_str;
  shy::jsonUtil::Serialize(root , json_str);
  std::cout << json_str << std::endl;

}

void Useage()
{
  std::cout << "./main + FileName" << std::endl;
  return;
}

void ConfigTest()
{
  cloud::Config* config = cloud::Config::GetInstance();
  std::cout << config->GetHotTime() << std::endl;
  std::cout << config->GetServerIP() << std::endl;
  std::cout << config->GetSetverPort() << std::endl;
  std::cout << config->GetPackfileSuffix() << std::endl;
}


void DataTest(const std::string& filename)
{
  cloud::BackupInfo info;
  info.NewBackupInfo(filename); 
  cloud::DataManager data;
  data.Insert(info);

  cloud::BackupInfo tmp;
  data.GetOneByURL("/download/bundle.h", &tmp);
  std::cout << "test getonebyrul" << std::endl;
  std::cout << tmp.pack_flag << std::endl;
  std::cout << tmp.fsize << std::endl;
  std::cout << tmp.mtime << std::endl;
  std::cout << tmp.atime << std::endl;
  std::cout << tmp.real_path << std::endl;
  std::cout << tmp.pack_path << std::endl; 
  std::cout << tmp.url << std::endl;

  info.pack_flag = true;
  data.Update(info);
  std::vector<cloud::BackupInfo> arry;
  data.GetAll(&arry);
  std::cout << "test getall" << std::endl;
  for (auto x : arry)
  {
    std::cout << x.pack_flag << std::endl;
    std::cout << x.fsize << std::endl;
    std::cout << x.mtime << std::endl;
    std::cout << x.atime << std::endl;
    std::cout << x.real_path << std::endl;
    std::cout << x.pack_path << std::endl;
    std::cout << x.url << std::endl;
  }

  data.GetOneByRealPath(tmp.real_path ,&tmp);
  std::cout << "test getonebyrealpath" << std::endl;
  std::cout << "--------------------------" << std::endl;
  std::cout << tmp.pack_flag << std::endl;
  std::cout << tmp.fsize << std::endl;
  std::cout << tmp.mtime << std::endl;
  std::cout << tmp.atime << std::endl;
  std::cout << tmp.real_path << std::endl;
  std::cout << tmp.pack_path << std::endl; 
  std::cout << tmp.url << std::endl;

  data.Storage();
}

void DataTest2()
{
  cloud::DataManager data;
  std::vector<cloud::BackupInfo> arry;
  data.GetAll(&arry);
  std::cout << "test getall" << std::endl;
  for (auto x : arry)
  {
    std::cout << x.pack_flag << std::endl;
    std::cout << x.fsize << std::endl;
    std::cout << x.mtime << std::endl;
    std::cout << x.atime << std::endl;
    std::cout << x.real_path << std::endl;
    std::cout << x.pack_path << std::endl;
    std::cout << x.url << std::endl;
  }

}

cloud::DataManager* _data;
void HotTest()
{
  cloud::HotManager hot;
  hot.RunModule();
}

void ServiceTest()
{
  cloud::Service srv;
  srv.RunModule();
}

int main(int argc , char* argv[])
{
  _data = new cloud::DataManager();
  std::thread thread_hot_manager(HotTest); 
  std::thread thread_service(ServiceTest);
  thread_hot_manager.join();
  thread_service.join();
  return 0;
}
